﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace vJine.Core.IoC {
    public delegate object OnRaise<Tstate>(Tstate State, object[] EventArgs);

    public class EventStatus : IDisposable {
        private EventStatus() {
        }

        internal EventStatus(string Key, EventInfo Event, Delegate Hooker, object objContext, object Context, object Status) {
            this.Key = Key;
            this.Event = Event; this.Hooker = Hooker;
            this.objContext = objContext; this.Context = Context;
            this.Status = Status;
        }

        string Key { get; set; }

        EventInfo Event { get; set; }

        Delegate Hooker { get; set; }

        object objContext { get; set; }

        internal static MethodInfo miGetContext =
            Reflect.GetProperty<EventStatus>("Context").GetGetMethod(true);
        object Context { get; set; }

        internal static MethodInfo miGetStatus =
            Reflect.GetProperty<EventStatus>("Status").GetGetMethod(true);
        object Status { get; set; }

        private bool _Enabled = false;
        public bool Enabled {
            get {
                return this._Enabled;
            }
            set {
                if (value) {
                    this.Enable_Set();
                } else {
                    this.Enable_Reset();
                }
            }
        }

        void Enable_Set() {
            lock (this.Hooker) {
                if (this._Enabled) {
                    return;
                }

                this.Event.AddEventHandler(this.objContext, this.Hooker);
                this._Enabled = true;
            }
        }

        void Enable_Reset() {
            lock (this.Hooker) {
                if (!this._Enabled) {
                    return;
                }

                this.Event.RemoveEventHandler(this.Context, this.Hooker);
                this._Enabled = false;
            }
        }

        public void Dispose() {
            lock (Emit.CacheEventStatus) {
                this.Enabled = false;
                Emit.CacheEventStatus[this.Key] = null;
                Emit.CacheEventStatus.Remove(this.Key);
            }
        }
    }
}
